from flask import Blueprint, request, jsonify
from app import db
from app.models.sync_task import SyncTask
from app.models.datasource import DataSource
from app.services.sync_service import start_sync_task, stop_sync_task
import json
from datetime import datetime

sync_task_bp = Blueprint('sync_task', __name__)

@sync_task_bp.route('/', methods=['GET'])
def get_sync_tasks():
    """获取所有同步任务"""
    tasks = SyncTask.query.all()
    return jsonify({
        'code': 200,
        'data': [task.to_dict() for task in tasks]
    })

@sync_task_bp.route('/<int:id>', methods=['GET'])
def get_sync_task(id):
    """获取单个同步任务"""
    task = SyncTask.query.get_or_404(id)
    return jsonify({
        'code': 200,
        'data': task.to_dict()
    })

@sync_task_bp.route('/', methods=['POST'])
def create_sync_task():
    """创建同步任务"""
    data = request.json
    
    # 检查必填字段
    required_fields = ['name', 'source_id', 'target_id', 'sync_configs', 'sync_type']
    for field in required_fields:
        if field not in data:
            return jsonify({
                'code': 400,
                'message': f'缺少必填字段: {field}'
            })
    
    # 验证同步配置
    sync_configs = data.get('sync_configs', [])
    if not sync_configs or len(sync_configs) == 0:
        return jsonify({
            'code': 400,
            'message': '至少需要配置一个同步表'
        })
    
    # 验证每个同步配置
    for i, config in enumerate(sync_configs):
        required_config_fields = ['source_table', 'target_table', 'field_mapping']
        for field in required_config_fields:
            if field not in config:
                return jsonify({
                    'code': 400,
                    'message': f'同步配置 {i+1} 缺少必填字段: {field}'
                })
    
    # 检查名称是否已存在
    if SyncTask.query.filter_by(name=data['name']).first():
        return jsonify({
            'code': 400,
            'message': '同步任务名称已存在'
        })
    
    # 检查数据源是否存在
    source = DataSource.query.get(data['source_id'])
    target = DataSource.query.get(data['target_id'])
    if not source or not target:
        return jsonify({
            'code': 400,
            'message': '数据源不存在'
        })
    
    # 创建同步任务
    task = SyncTask(
        name=data['name'],
        source_id=data['source_id'],
        target_id=data['target_id'],
        sync_type=data['sync_type'],
        sync_frequency=data.get('sync_frequency'),
        thread_count=data.get('thread_count', 1),
        batch_size=data.get('batch_size', 1000),
        sync_configs=json.dumps(data['sync_configs'])
    )
    
    db.session.add(task)
    db.session.commit()
    
    return jsonify({
        'code': 201,
        'message': '同步任务创建成功',
        'data': task.to_dict()
    })

@sync_task_bp.route('/<int:id>', methods=['PUT'])
def update_sync_task(id):
    """更新同步任务"""
    task = SyncTask.query.get_or_404(id)
    data = request.json
    
    # 如果任务正在运行，不允许更新
    if task.status == 'running':
        return jsonify({
            'code': 400,
            'message': '任务正在运行，无法更新'
        })
    
    # 更新字段
    if 'name' in data and data['name'] != task.name:
        # 检查名称是否已存在
        if SyncTask.query.filter_by(name=data['name']).first():
            return jsonify({
                'code': 400,
                'message': '同步任务名称已存在'
            })
        task.name = data['name']
    
    if 'source_id' in data:
        # 检查数据源是否存在
        source = DataSource.query.get(data['source_id'])
        if not source:
            return jsonify({
                'code': 400,
                'message': '源数据源不存在'
            })
        task.source_id = data['source_id']
    
    if 'target_id' in data:
        # 检查数据源是否存在
        target = DataSource.query.get(data['target_id'])
        if not target:
            return jsonify({
                'code': 400,
                'message': '目标数据源不存在'
            })
        task.target_id = data['target_id']
    
    if 'sync_type' in data:
        task.sync_type = data['sync_type']
    if 'sync_frequency' in data:
        task.sync_frequency = data['sync_frequency']
    if 'thread_count' in data:
        task.thread_count = data['thread_count']
    if 'batch_size' in data:
        task.batch_size = data['batch_size']
    if 'sync_configs' in data:
        # 验证同步配置
        sync_configs = data['sync_configs']
        if not sync_configs or len(sync_configs) == 0:
            return jsonify({
                'code': 400,
                'message': '至少需要配置一个同步表'
            })
        task.sync_configs = json.dumps(sync_configs)
    
    db.session.commit()
    
    return jsonify({
        'code': 200,
        'message': '同步任务更新成功',
        'data': task.to_dict()
    })

@sync_task_bp.route('/<int:id>', methods=['DELETE'])
def delete_sync_task(id):
    """删除同步任务"""
    task = SyncTask.query.get_or_404(id)
    
    # 如果任务正在运行，不允许删除
    if task.status == 'running':
        return jsonify({
            'code': 400,
            'message': '任务正在运行，无法删除'
        })
    
    db.session.delete(task)
    db.session.commit()
    
    return jsonify({
        'code': 200,
        'message': '同步任务删除成功'
    })

@sync_task_bp.route('/<int:id>/start', methods=['POST'])
def start_task(id):
    """启动同步任务"""
    task = SyncTask.query.get_or_404(id)
    
    # 如果任务已经在运行，返回错误
    if task.status == 'running':
        return jsonify({
            'code': 400,
            'message': '任务已经在运行'
        })
    
    # 启动任务
    success, message = start_sync_task(task)
    
    if success:
        # 更新任务状态
        task.status = 'running'
        task.last_sync_time = datetime.now()
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '任务启动成功'
        })
    else:
        return jsonify({
            'code': 400,
            'message': f'任务启动失败: {message}'
        })

@sync_task_bp.route('/<int:id>/stop', methods=['POST'])
def stop_task(id):
    """停止同步任务"""
    task = SyncTask.query.get_or_404(id)
    
    # 如果任务没有在运行，返回错误
    if task.status != 'running':
        return jsonify({
            'code': 400,
            'message': '任务没有在运行'
        })
    
    # 停止任务
    success, message = stop_sync_task(task)
    
    if success:
        # 更新任务状态
        task.status = 'stopped'
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '任务停止成功'
        })
    else:
        return jsonify({
            'code': 400,
            'message': f'任务停止失败: {message}'
        })

@sync_task_bp.route('/datasources', methods=['GET'])
def get_datasources_for_task():
    """获取可用于任务的数据源列表"""
    datasources = DataSource.query.all()
    return jsonify({
        'code': 200,
        'data': [{'id': ds.id, 'name': ds.name, 'type': ds.type} for ds in datasources]
    })